Inheritance is one of the features of Object-Oriented Programming. According to this feature, the child class can inherit or access the public properties and methods of the parent class. In Python, we do not have access modifiers to separate public or private properties of a parent class, this means, in Python, the child class can inherit all the properties and methods of its parent class. The parent class and child class terminologies are also referred to as base class and drive class. This Python tutorial will teach Python inheritance , method overloading, method overriding, inheritance types, and Method Resolution order.
What is Inheritance in Python?
As we know that inheritance is one of the features of OOP and it is used too often. According to the inheritance concept we can use the properties of one class in another class, and these properties could be its class methods and attributes. In Inheritance, we require at least two classes base and derived . The base class will be a normal class but the derived class will have some modification in its syntax. We could also consider base class as a parent class and derived class as a child class.
Python Inheritance Syntax
class base:
# base class block
class derived(base):
# derived class block
To inherit the base class we pass the base class name as an argument to the derived class.
Inheritance example
#base or parent class
class Student:
def get(self):
self.roll = int(input("Please enter the roll no.: "))
self.m1 = int(input("Please enter the M1 marks: "))
self.m2 = int(input("Please enter the M2 marks: "))
self.ea = int(input("Please enter the extra activity marks: "))
# Derived or child class
class Output(Student):
def display(self):
#accessing parent class attributes or variables
self.total = self.m1 + self.m2 + self.ea
print("Roll No.",self.roll, "total marks are: ", self.total )
student = Output()
student.get()
student.display()
#Output
Please enter the roll no.: 10
Please enter the M1 marks: 95
Please enter the M2 marks: 94
Please enter the extra activity marks: 98
Roll No. 10 total marks are: 28
Behind the code
In the above example, we have defined 2 classes Student and Output , here Student is the base class whereas Output is the derived class which means the Output class can inherit the properties of the Student class. In Student class we have defined all the attributes ( roll , m1 , m2 , and ea ) inside the get () method and access those attributes in the Output class display() method where we make the total . In the above program we did not create the object of Student class only with the help of Output object student we accessed the Student get() method to take input from the user and use those inputs in display() method. This inherits property used by Output class in which it accessed the Student class attributes and get () method prove that in python class can follow the inheritance property. The main objective of inheritance in Python or any other programming language is the reusability of code, by inheriting the parent class we do not need to write the same logic for the child class. This type of technique comes very handy in big projects where many sub-sections require the same properties as the main section.
Types of Inheritance
The type of inheritance in Python depends upon the relationship between the chile and parent classes. There are five types of inheritance in Python.
- Single Inheritance
- Multiple Inheritance
- Multilevel Inheritance
- Hierarchical Inheritance
- Hybrid Inheritance
Now let’s discuss all these inheritance types one by one with examples
Single Inheritance In Python
In Single Inheritance, there is one parent class and one child class, and the child class directly inherits from the single parent class.
Single Inheritance Syntax
class parent():
#parent class body
class child(parent):
#child class body
Example
Let’s create two classes Car and BMW, and perform single inheritance where the BMW class inherit the Car class.
#parent class
class Car():
def car_wheel(self):
print("This car has 4 wheelss")
#child class inheriting Car Class
class BMW(Car):
def model_info(self):
print("This is a BMW M1")
#create an object of child class BMW
bmw = BMW()
#access the Car method using bmw object
bmw.car_wheel()
#access the BMW method using bmw object
bmw.model_info()
Output
This car has 4 wheelss
This is a BMW M1
Behind the code
In the above example, we perform the single inheritance. The Car was the base class that was inherited by the single drive class BMW.
Multiple Inheritance In Python
In multiple inheritance, a single child class can inherit from two or more than two parents classes.
Multiple Inheritance Syntax
class parent1():
#parent1 class body
class parent2():
#parent2 class body
class child(parent1, parent2):
#child class body
Example
Let’s write a script in Python that demonstrates Python Multiple Inheritance, for multiple inheritance, there must be at least two parent classes.
class RTO():
def car_current_owner(self, name):
print("This car owner is :", name)
#parent class
class Car():
def car_wheel(self):
print("This car has 4 wheels")
#child class inheriting Car and RTO classes
class BMW(Car, RTO):
def model_info(self):
print("This is a BMW M1")
#create an object of child class BMW
bmw = BMW()
#access the Car method using bmw object
bmw.car_wheel()
#access the RTO car_registary() method with bmw object
bmw.car_current_owner('Rohan')
#access the BMW method using bmw object
bmw.model_info()
Output
This car has 4 wheels
This car owner is: Rohan
This is a BMW M1
Behind the code
In this multiple inheritance example, the child class BMW inherited properties from two parent classes RTO and Car. Because of multiple inheritances, bmw object is able to access the car_wheel() and car_current_owner() methods which belong to the parent class.
Multilevel Inheritance In Python
In Multilevel Inheritance, the child class can be the parent class of another class. Let’s say we have three classes, A, B, and C. Where A is the parent class of B and B is the parent class of C. Making B the child and C the grandchild of class A. Here A does not have any parent class which makes a SuperClass.
Multilevel Inheritance Syntax
class parent():
#superclass body
class child1(parent):
#child 1 body
class child2(child1):
#child 2 body
In multilevel inheritance, the last child ultimately inherits the properties of all the above parents.
Multilevel Inheritance Example
#parent class
class Car():
def car_wheel(self):
print("This car has 4 wheels")
#child class inheriting Car class
class BMW(Car):
def model_info(self):
print("This is a BMW M1")
#child class inheriting BMW classes
class Showroom(BMW):
def bmw_car(self):
print("Only One BMW car is available")
#create an object of child class Showroom
showroom = Showroom()
#access Showroom bmw_car() method
showroom.bmw_car()
#access the BMW method using showroom object
showroom.model_info()
#access the Car method using showroom object
showroom.car_wheel()
Output
Only One BMW car is available
This is a BMW M1
This car has 4 wheels
Behind the code
In this example, we perform multilevel inheritance using Car , BMW , and Showroom classes. The attribute access in Multilevel inheritance flow from down to up, or from child to parent. Similarly in the above example, the Showroom class is able to inherit BMW , as well as Car properties.
Hierarchical Inheritance In Python
In Hierarchical inheritance, we have one parent class that is inherited by two or more two-child classes.
Hierarchical Inheritance Syntax
class parent():
#parent class body
class child1(parent):
#child1 class body
class child2(parent):
#child2 class body
class child3(parent):
#child3 class body
Hierarchical Inheritance Example
#parent class
class Car():
def car_wheel(self):
print("This car has 4 wheels")
#child class inheriting Car class
class BMW(Car):
def model_info(self):
print("This is a BMW M1")
#child class inheriting Car class
class Audi(Car):
def model_info(self):
print("This is an Audi A6 Sedan")
#child class inheriting Car class
class Mercedes(Car):
def model_info(self):
print("This is a Mercedes Benz E Class")
#create an object of child class BMW
bmw = BMW()
bmw.model_info()
bmw.car_wheel()
#create an object of child class Audi
audi = Audi()
audi.model_info()
audi.car_wheel()
Output
This is a BMW M1
This car has 4 wheels
This is an Audi A6 Sedan
This car has 4 wheels
Hybrid Inheritance In Python
In Hybrid inheritance, the relationship between different classes is a combination of all the inheritance we have discussed in the above examples.
Syntax
class parent():
#parent class body
class child1(parent):
#child1 class body
class child2(parent):
#child2 class body
class child3(child1, child2):
#child 3 class body
Hybrid Inheritance Example
#parent class
class Car():
def car_wheel(self):
print("This car has 4 wheels")
#child class inheriting Car class
class BMW(Car):
def model_info(self):
print("This is a BMW M1")
#child class inheriting Car class
class Service(Car):
def service_info(self):
print("Car Service is also available")
#child class inheriting BMW and Service classes
class Showroom(BMW, Service):
def availability(self):
print("Only one BMW car is available right now")
#creating the object of Showroom
showroom = Showroom()
#access Showroom's method with showroom object
showroom.availability()
#access BMW's method with showroom object
showroom.model_info()
#access Service's method with showroom object
showroom.service_info()
#access Car's method with showroom object
showroom.car_wheel()
Output
Only one BMW car is available right now
This is a BMW M1
Car Service is also available
This car has 4 wheels
Python Super function
When a child class inherits a parent class, the child class becomes the subclass of the parent class, where the parent class is known as a superclass. When we want to call or access a parent class method inside a child class, we can either use the object or the name of the parent class. But Python provides a super() function, which creates a proxy or temporary object of the parent class so we can access the parent class method inside the child class.
Benefits of using the super() function
- With the super function, we do not need to use the parent class name while accessing the parent methods.
- It can work with both single and multiple inheritance.
- It comes very handy during function or method overloading.
Super Function with Single inheritance
In single inheritance, the super() function directly refers to the superclass of the child method that is the parent class.
Example
#parent class
class Car():
def __init__(self):
print("This vehicle is a car ")
#child class
class BMW(Car):
def __init__(self):
print("This is a BMW car")
#call the super class(Car) init method
super().__init__()
#create the object of BMW class
bmw = BMW()
Output
This is a BMW car
This vehicle is a car
Break the code
In the above example when we created the object of BMW() class bmw, it automatically call its __init__() function. And inside its __init__() function we have called its superclass’s ( Car ) __init__() function using super().__init__() statement.
Super Function with Multiple inheritances
In multiple inheritances, the super function refers to the superclass according to the Method Resolution Order.
Example
#parent class
class RTO():
def __init__(self):
print("This Car comes under RTO")
#child class
class Car():
def __init__(self):
print("This vehicle is a car ")
#here super is the object of BMW
#when it is called by BMW object
#else it is the object of Car itself
super().__init__()
#child class
class BMW(Car, RTO):
def __init__(self):
print("This is a BMW car")
#call the super classes Car
super().__init__()
#create the object of BMW class
bmw = BMW()
Output
This is a BMW car
This vehicle is a car
This Car comes under RTO
Break the code
In the above example the super().__init__() statement of the BMW class call the Car’s class, and the super().__init__() statement inside the Car’s class call the RTO’s class __init__() method.
Method Overriding
When a child class inherits a parent class, it inherits the parent’s all properties such as methods and attributes. But if any method of the parent class does not satisfy the child class, the child class can have a method of itself with the same method name as the parent class. This redefining of the same method in the child class is known as method overriding .
Let’s understand it with an example:
class Animal:
def __init__(self,name):
self.name= name
print(self.name,"Animal")
def speak(self):
print(" Voice ")
class Cat(Animal):
def speak(self):
print(self.name,"speak meow")
tom = Cat("tom") #this will invoke the animal __init__ method because cat does not have __init__
tom.speak() #this will invoke cat speak method
#Output
tom Animal
tom speak meow
Behind the Code
In the above code when we create the Cat classe’s object tom and we pass a name “tom” along with the class cat(“tom”) this will invoke the Animal class constructor that is __init__() because the cat class does not have any __init__ method. But when we use the tom object and call the speak method then the Cat class’s speak() method gets invoked not the Animal class speak() method why so? because the interpreter first looks at all the methods of Cat class if the Cat class did not have the speak method then it would call the Animal speak method. The calling of methods by the objects depends upon the Method Resolution Order now let’s discuss what it is?
What is Method Resolution Order in Python?
The Method Resolution Order is an order followed by Python to look up for the methods or attributes of a class object. The order generally goes from down to up, which means from child to parent. The MRO plays a very crucial role in multiple inheritance and method overriding. The Method Resolution Order of a Class can be seen using the mro() method.
Example
Let’s see an example of multiple inheritance and how the order of method accessing followed by it.
class A():
def method(self):
print("This method is inside class A")
class B():
def method(self):
print("This method is inside class B")
class C(B, A):
def method(self):
print("This method is inside class C")
#create the object of class C
c = C()
#call the method() on object c
#it will call the method defined inside the C class
c.method()
#print the Method Resolution Order
print(C.mro())
Output
This method is inside class C
[<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
Break the code
In the above example, the C inherits from B and A , that’s why when we call the method() method on class object c it calls the method() inside the Class C because it has high priority. The output of C.mro() list shows the order in which the c object should look for the methods. While initializing the class C, we set inheritance as ( B, A) , and because Python read from left to right B has the higher priority than A .